<template>
  <div class="page">
    <el-card class="box-card">
      <!-- title -->
      <h3 class="title3">{{ title }}</h3>
      <div v-if="hasArticle && !isLoading" class="article-list-wrapper">
        <ArticleItem @click="handleEdit(article._id)" v-for="article in articles" :key="article._id"
          :title="article.title" :desc="article.desc || article.content"
          :date="article.publishDate || article.createDate">
          <template #after>
            <!-- 操作按钮 -->
            <!-- XXX: 封装成组件 -->
            <div class="option-wrapper">
              <div>
                <el-button @click.stop="handleDelete(article._id)" class="option-btn" type="danger" circle>
                  <el-icon>
                    <Delete />
                  </el-icon>
                </el-button>
              </div>
              <div>
                <el-button @click.stop="handleEdit(article._id)" class="option-btn" type="primary" circle>
                  <el-icon>
                    <Edit />
                  </el-icon>
                </el-button>
              </div>
            </div>
          </template>
        </ArticleItem>
      </div>
      <div v-else-if="!isLoading" class="not-article">
        暂无任何文章...
      </div>
      <div v-else v-loading="isLoading" class="loading-wrapper"></div>
    </el-card>
  </div>
</template>

<script>
import ArticleItem from '@/components/ArticleItem.vue'
import { Delete, Edit } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { mapState } from 'vuex'
import api from '@/api'

export default {
  name: 'ArticleListView',
  components: {
    ArticleItem,
    Delete,
    Edit
  },
  props: {
    type: {
      validator(value) {
        return ['publish', 'unpublish'].includes(value)
      }
    }
  },
  data() {
    return {
      articles: [],
      isLoading: false,
    }
  },
  computed: {
    title() {
      return this.type === 'publish' ? '已发布文章' : '未发布文章'
    },
    hasArticle() {
      // 注意:使用 this.articles.length > 0 无法被vue监听
      return this.articles[0]
    },
    ...mapState({
      uid: state => state.user._id
    })
  },
  mounted() {
    console.log('uid:', this.uid)
    this.loadArticle()
  },
  beforeUpdate() {
    console.log('ArticleListView beforeUpdate')
    this.loadArticle()
  },
  methods: {
    loadArticle() {
      this.isLoading = true
      let apiPromise = null

      // 至少让加载界面加载一段时间
      let isTimeout = false
      let isFinally = false
      setTimeout(() => {
        isTimeout = true
        if (isFinally) {
          this.isLoading = false
        }
      }, 600)

      // 数据请求
      if (this.type === 'publish') {
        apiPromise = api.article.getPublish(this.uid)
      } else {
        apiPromise = api.article.getUnpublish()
      }

      apiPromise.then(result => {
        this.articles = result.data.articles
      }).catch(() => {
        this.articles = []
      }).finally(() => {
        isFinally = true
        if (isTimeout) {
          this.isLoading = false
        }
      })
    },
    handleDelete(id) {
      ElMessageBox.confirm(
        '是否确定删除？',
        '消息',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'info',
        }
      ).then(() => {
        api.article.deleteArticle(id).then(() => {
          this.loadArticle()
          ElMessage.success('删除成功')
        })
      }).catch(() => {
        console.log('cancel')
      })
    },
    handleEdit(id) {
      this.$router.push({ name: 'article-editor', params: { id } })
    }
  }
}
</script>

<style lang="scss" scoped>
.option-wrapper {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-end;
  width: 56px;

  .option-btn {
    margin-bottom: 10px;
  }
}

.not-article {
  text-align: center;
  color: var(--el-text-color-secondary);
}
</style>
